﻿' Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.

Imports System
Imports Microsoft.CodeAnalysis.ExpressionEvaluator
Imports Microsoft.VisualStudio.Debugger.Clr
Imports Microsoft.VisualStudio.Debugger.Evaluation
Imports Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation
Imports Xunit

Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator.UnitTests

    Public Class ValueFormatterTests : Inherits VisualBasicResultProviderTestBase

        <Fact>
        Public Sub IntegralPrimitives()
            ' only testing a couple simple cases here...more tests live in ObjectDisplayTests...
            Assert.Equal("1", FormatValue(CUShort(1)))
            Assert.Equal("65535", FormatValue(UShort.MaxValue))
            Assert.Equal("1", FormatValue(CInt(1)))
            Assert.Equal("-1", FormatValue(CInt(-1)))

            Assert.Equal("&H00", FormatValue(CSByte(0), useHexadecimal:=True))
            Assert.Equal("&H01", FormatValue(CSByte(1), useHexadecimal:=True))
            Assert.Equal("&HFFFFFFFF", FormatValue(CSByte(-1), useHexadecimal:=True))
            Assert.Equal("&H0000000000000000", FormatValue(CULng(0), useHexadecimal:=True))
            Assert.Equal("&H0000000000000001", FormatValue(CULng(1), useHexadecimal:=True))
            Assert.Equal("&HFFFFFFFFFFFFFFFF", FormatValue(ULong.MaxValue, useHexadecimal:=True))
        End Sub

        <Fact>
        Public Sub Doubles()
            Assert.Equal("-1.7976931348623157E+308", FormatValue(Double.MinValue))
            Assert.Equal("-1.1", FormatValue(CDbl(-1.1)))
            Assert.Equal("0", FormatValue(CDbl(0)))
            Assert.Equal("1.1", FormatValue(CDbl(1.1)))
            Assert.Equal("1.7976931348623157E+308", FormatValue(Double.MaxValue))

            Assert.Equal("-Infinity", FormatValue(Double.NegativeInfinity))
            Assert.Equal("Infinity", FormatValue(Double.PositiveInfinity))
            Assert.Equal("NaN", FormatValue(Double.NaN))
            Assert.Equal("4.94065645841247E-324", FormatValue(Double.Epsilon))
        End Sub

        <Fact>
        Public Sub Singles()
            Assert.Equal("-3.40282347E+38", FormatValue(Single.MinValue))
            Assert.Equal("-1.1", FormatValue(CSng(-1.1)))
            Assert.Equal("0", FormatValue(CSng(0)))
            Assert.Equal("1.1", FormatValue(CSng(1.1)))
            Assert.Equal("3.40282347E+38", FormatValue(Single.MaxValue))

            Assert.Equal("-Infinity", FormatValue(Single.NegativeInfinity))
            Assert.Equal("Infinity", FormatValue(Single.PositiveInfinity))
            Assert.Equal("NaN", FormatValue(Single.NaN))
            Assert.Equal("1.401298E-45", FormatValue(Single.Epsilon))
        End Sub

        <Fact>
        Public Sub Decimals()
            Assert.Equal("-79228162514264337593543950335", FormatValue(Decimal.MinValue))
            Assert.Equal("-1.1", FormatValue(CDec(-1.1)))
            Assert.Equal("0", FormatValue(CDec(0)))
            Assert.Equal("1.1", FormatValue(CDec(1.1)))
            Assert.Equal("79228162514264337593543950335", FormatValue(Decimal.MaxValue))
        End Sub

        <Fact>
        Public Sub Booleans()
            Assert.Equal("True", FormatValue(True))
            Assert.Equal("False", FormatValue(False))
        End Sub

        <Fact>
        Public Sub Chars()
            ' We'll exhaustively test the first 256 code points (single-byte characters) as well
            ' as a few double-byte characters.  Testing all possible characters takes too long.
            Dim ch As Char
            For i = 0 To &HFF
                ch = ChrW(i)
                Dim expected As String
                Dim expectedHex As String = Nothing
                ' NOTE: The old EE used to just display " " for non-printable characters.
                '       This has been changed in Roslyn to display the equivalent VB constants
                '       or the actual numeric code point value (this seems far more useful).
                Select Case CStr(ch)
                    Case vbNullChar
                        expected = "vbNullChar"
                    Case vbBack
                        expected = "vbBack"
                    Case vbCr
                        expected = "vbCr"
                    Case vbFormFeed
                        expected = "vbFormFeed"
                    Case vbLf
                        expected = "vbLf"
                    Case vbTab
                        expected = "vbTab"
                    Case vbVerticalTab
                        expected = "vbVerticalTab"
                    Case """"c
                        expected = """""""""c"
                    Case Else
                        If ObjectDisplay.IsPrintable(ch) Then
                            expected = """" & ch & """c"
                        Else
                            expected = "ChrW(" & i & ")"
                            expectedHex = "ChrW(&H" & i.ToString("X") & ")"
                        End If
                End Select

                Assert.Equal(expected, FormatValue(ch))
                Assert.Equal(If(expectedHex, expected), FormatValue(ch, useHexadecimal:=True))
            Next

            For Each ch In {ChrW(&HABCD), ChrW(&HFEEF)}
                Assert.Equal("""" & ch & """c", FormatValue(ch))
                Assert.Equal("""" & ch & """c", FormatValue(ch, useHexadecimal:=True))
            Next

            ch = ChrW(&HFFEF)
            Assert.Equal("ChrW(65519)", FormatValue(ch))
            Assert.Equal("ChrW(&HFFEF)", FormatValue(ch, useHexadecimal:=True))

            Assert.Equal("ChrW(65535)", FormatValue(Char.MaxValue))
            Assert.Equal("ChrW(&HFFFF)", FormatValue(Char.MaxValue, useHexadecimal:=True))
        End Sub

        <Fact>
        Public Sub Strings()
            Assert.Equal("Nothing", FormatNull(Of String)())
            Assert.Equal("Nothing", FormatNull(Of String)(useHexadecimal:=True))

            ' We'll exhaustively test the first 256 code points (single-byte characters) as well
            ' as a few multi-byte characters.  Testing all possible characters takes too long.
            Dim ch As Char
            For i = 0 To &HFF
                ch = ChrW(i)
                Dim s As String = "a" & ch
                Dim expected As String
                Dim expectedHex As String = Nothing
                Select Case CStr(ch)
                    Case vbNullChar
                        expected = """a"" & vbNullChar"
                    Case vbTab
                        expected = """a"" & vbTab"
                    Case vbCr
                        expected = """a"" & vbCr"
                    Case vbFormFeed
                        expected = """a"" & vbFormFeed"
                    Case vbLf
                        expected = """a"" & vbLf"
                    Case vbBack
                        expected = """a"" & vbBack"
                    Case vbVerticalTab
                        expected = """a"" & vbVerticalTab"
                    Case """"
                        expected = """a"""""""
                    Case Else
                        If ObjectDisplay.IsPrintable(ch) Then
                            expected = """" & s & """"
                        Else
                            expected = """a"" & ChrW(" & i & ")"
                            expectedHex = """a"" & ChrW(&H" & i.ToString("X") & ")"
                        End If
                End Select

                Assert.Equal(expected, FormatValue(s))
                Assert.Equal(If(expectedHex, expected), FormatValue(s, useHexadecimal:=True))
            Next

            Assert.Equal("""a"" & vbNullChar & ""b""", FormatValue("a" & vbNullChar & "b"))

            For Each ch In {ChrW(&HABCD), ChrW(&HFEEF)}
                Assert.Equal("""" & ch & """", FormatValue(CStr(ch)))
                Assert.Equal("""" & ch & """", FormatValue(CStr(ch), useHexadecimal:=True))
            Next

            ch = ChrW(&HFFEF)
            Assert.Equal("ChrW(65519)", FormatValue(ch))
            Assert.Equal("ChrW(&HFFEF)", FormatValue(ch, useHexadecimal:=True))

            Assert.Equal("ChrW(65535)", FormatValue(CStr(Char.MaxValue)))
            Assert.Equal("ChrW(&HFFFF)", FormatValue(CStr(Char.MaxValue), useHexadecimal:=True))

            Dim multiByte = ChrW(&HD83C) & ChrW(&HDFC8)
            Assert.Equal("""🏈""", FormatValue(multiByte))
            Assert.Equal("""🏈""", FormatValue(multiByte, useHexadecimal:=True))
            Assert.Equal("🏈", multiByte)

            multiByte = ChrW(&HDFC8) & ChrW(&HD83C)
            Assert.Equal("ChrW(57288) & ChrW(55356)", FormatValue(multiByte))
            Assert.Equal("ChrW(&HDFC8) & ChrW(&HD83C)", FormatValue(multiByte, useHexadecimal:=True))
        End Sub

        <Fact>
        Public Sub Void()
            ' Something happens but, in practice, we expect the debugger to recognize
            ' that the value is of type void and turn it into the error string 
            ' "Expression has been evaluated and has no value".
            Assert.Equal("{System.Void}", FormatValue(Nothing, GetType(Void)))
        End Sub

        <Fact>
        Public Sub InvalidValue_1()
            Const errorMessage = "An error has occurred."
            Dim clrValue = CreateDkmClrValue(errorMessage, GetType(String), evalFlags:=DkmEvaluationResultFlags.None, valueFlags:=DkmClrValueFlags.Error)
            Assert.Equal(errorMessage, (DirectCast(FormatResult("invalidIdentifier", clrValue), DkmFailedEvaluationResult)).ErrorMessage)
        End Sub

        <Fact>
        Public Sub InvalidValue_2()
            Const errorMessage = "An error has occurred."
            Dim clrValue = CreateDkmClrValue(errorMessage, GetType(Integer), evalFlags:=DkmEvaluationResultFlags.None, valueFlags:=DkmClrValueFlags.Error)
            Assert.Equal(errorMessage, (DirectCast(FormatResult("invalidIdentifier", clrValue), DkmFailedEvaluationResult)).ErrorMessage)
        End Sub

        <Fact>
        Public Sub NonFlagsEnum()
            Dim source = "
Enum E
    A = 1
    B = 2
End Enum
"
            Dim assembly = GetAssembly(source)

            Dim type = assembly.GetType("E")

            Assert.Equal("0", FormatValue(0, type))
            Assert.Equal("A {1}", FormatValue(1, type))
            Assert.Equal("B {2}", FormatValue(2, type))
            Assert.Equal("3", FormatValue(3, type))
        End Sub

        <Fact>
        Public Sub NonFlagsEnum_Negative()
            Dim source = "
Enum E
    A = -1
    B = -2
End Enum
"
            Dim assembly = GetAssembly(source)

            Dim type = assembly.GetType("E")

            Assert.Equal("0", FormatValue(0, type))
            Assert.Equal("A {-1}", FormatValue(-1, type))
            Assert.Equal("B {-2}", FormatValue(-2, type))
            Assert.Equal("-3", FormatValue(-3, type))
        End Sub

        <Fact>
        Public Sub NonFlagsEnum_Order()
            Dim source = "
Enum E1
    A = 1
    B = 1
End ENum

Enum E2
    B = 1
    A = 1
End Enum
"
            Dim assembly = GetAssembly(source)

            Dim e1 = assembly.GetType("E1")
            Dim e2 = assembly.GetType("E2")

            ' VB always picks field that is lexically "first"
            Assert.Equal("A {1}", FormatValue(1, e1))
            Assert.Equal("A {1}", FormatValue(1, e2))
        End Sub

        <Fact>
        Public Sub FlagsEnum()
            Dim source = "
Imports System

<Flags>
Enum E
    A = 1
    B = 2
End Enum
"
            Dim assembly = GetAssembly(source)

            Dim type = assembly.GetType("E")

            Assert.Equal("0", FormatValue(0, type))
            Assert.Equal("A {1}", FormatValue(1, type))
            Assert.Equal("B {2}", FormatValue(2, type))
            Assert.Equal("A Or B {3}", FormatValue(3, type))
            Assert.Equal("4", FormatValue(4, type))
        End Sub

        <Fact>
        Public Sub FlagsEnum_Zero()
            Dim source = "
Imports System

<Flags>
Enum E
    None = 0
    A = 1
    B = 2
End Enum
"
            Dim assembly = GetAssembly(source)

            Dim type = assembly.GetType("E")

            Assert.Equal("None {0}", FormatValue(0, type))
            Assert.Equal("A {1}", FormatValue(1, type))
            Assert.Equal("B {2}", FormatValue(2, type))
            Assert.Equal("A Or B {3}", FormatValue(3, type))
            Assert.Equal("4", FormatValue(4, type))
        End Sub

        <Fact>
        Public Sub FlagsEnum_Combination()
            Dim source = "
Imports System

<Flags>
Enum E
    None = 0
    A = 1
    B = 2
    C = A Or B
End Enum
"
            Dim assembly = GetAssembly(source)

            Dim type = assembly.GetType("E")

            Assert.Equal("None {0}", FormatValue(0, type))
            Assert.Equal("A {1}", FormatValue(1, type))
            Assert.Equal("B {2}", FormatValue(2, type))
            Assert.Equal("C {3}", FormatValue(3, type))
            Assert.Equal("4", FormatValue(4, type))
        End Sub

        <Fact>
        Public Sub FlagsEnum_Negative()
            Dim source = "
Imports System

<Flags>
Enum E
    None = 0
    A = -1
    B = -2
End Enum
"
            Dim assembly = GetAssembly(source)

            Dim type = assembly.GetType("E")

            Assert.Equal("None {0}", FormatValue(0, type))
            Assert.Equal("A {-1}", FormatValue(-1, type))
            Assert.Equal("B {-2}", FormatValue(-2, type))
            Assert.Equal("-3", FormatValue(-3, type))
            Assert.Equal("-4", FormatValue(-4, type))
        End Sub

        <Fact>
        Public Sub FlagsEnum_Order()
            Dim source = "
Imports System

<Flags>
Enum E1
    A = 1
    B = 1
    C = 2
    D = 2
End Enum

<Flags>
Enum E2
    D = 2
    C = 2
    B = 1
    A = 1
End Enum
"
            Dim assembly = GetAssembly(source)

            Dim e1 = assembly.GetType("E1")
            Dim e2 = assembly.GetType("E2")

            Assert.Equal("0", FormatValue(0, e1))
            Assert.Equal("A {1}", FormatValue(1, e1))
            Assert.Equal("C {2}", FormatValue(2, e1))
            Assert.Equal("A Or C {3}", FormatValue(3, e1))

            Assert.Equal("0", FormatValue(0, e2))
            Assert.Equal("A {1}", FormatValue(1, e2))
            Assert.Equal("C {2}", FormatValue(2, e2))
            Assert.Equal("A Or C {3}", FormatValue(3, e2))
        End Sub

        <Fact>
        Public Sub Arrays()
            Dim source = "
Namespace N
    Public Class A(Of T)
        Public Class B(Of U)
        End Class
    End Class
End Namespace
"
            Dim assembly = GetAssembly(source)
            Dim typeA = assembly.GetType("N.A`1")
            Dim typeB = typeA.GetNestedType("B`1")
            Dim constructedType = typeB.MakeGenericType(GetType(Boolean), GetType(Long))

            Dim vectorInstance = Array.CreateInstance(constructedType, 2)
            Dim matrixInstance = Array.CreateInstance(constructedType, 3, 4)
            Dim irregularInstance = Array.CreateInstance(constructedType, {1, 2}, {3, 4})

            Assert.Equal("{Length=2}", FormatValue(vectorInstance))
            Assert.Equal("{Length=12}", FormatValue(matrixInstance))
            Assert.Equal("{Length=2}", FormatValue(irregularInstance))

            Assert.Equal("{Length=2}", FormatValue(vectorInstance, useHexadecimal:=True))
            Assert.Equal("{Length=12}", FormatValue(matrixInstance, useHexadecimal:=True))
            Assert.Equal("{Length=2}", FormatValue(irregularInstance, useHexadecimal:=True))
        End Sub

        <Fact>
        Public Sub Pointers()
            Dim pointerType = GetType(Integer).MakePointerType()
            Dim doublePointerType = pointerType.MakePointerType()

            Assert.Equal("&H00000001", FormatValue(1, pointerType, useHexadecimal:=False)) ' In hex, regardless.
            Assert.Equal("&H00000001", FormatValue(1, pointerType, useHexadecimal:=True))

            Assert.Equal("&HFFFFFFFF", FormatValue(-1, doublePointerType, useHexadecimal:=False)) ' In hex, regardless.
            Assert.Equal("&HFFFFFFFF", FormatValue(-1, doublePointerType, useHexadecimal:=True))
        End Sub

        <Fact>
        Public Sub Nullable()
            Dim source = "
Namespace N
    Public Structure A(Of T)
        Public Structure B(Of U)
            Public Overrides Function ToString() As String
                Return ""ToString() called.""
            End Function
        End Structure
    End Structure
End Namespace
"
            Dim assembly = GetAssembly(source)
            Dim typeA = assembly.GetType("N.A`1")
            Dim typeB = typeA.GetNestedType("B`1")
            Dim constructedType = typeB.MakeGenericType(GetType(Boolean), GetType(Long))
            Dim nullableType = GetType(Nullable(Of ))
            Dim nullableConstructedType = nullableType.MakeGenericType(constructedType)
            Dim nullableInt = nullableType.MakeGenericType(GetType(Integer))

            Assert.Equal("Nothing", FormatValue(Nothing, nullableConstructedType))
            Assert.Equal("{ToString() called.}", FormatValue(constructedType.Instantiate(), nullableConstructedType))

            Assert.Equal("Nothing", FormatValue(Nothing, nullableInt))
            Assert.Equal("1", FormatValue(1, nullableInt))
        End Sub

        <Fact>
        Public Sub ToStringOverrides()
            Dim source = "
Public Class A(Of T)
End Class

Public Class B : Inherits A(Of Integer)
    Public Overrides Function ToString() As String
        Return ""B.ToString()""
    End Function
End Class

Public Class C : Inherits B
End Class
"
            Dim assembly = GetAssembly(source)
            Dim typeC = assembly.GetType("C")
            Dim typeB = assembly.GetType("B")
            Dim typeA = typeB.BaseType

            Assert.Equal("Nothing", FormatValue(Nothing, typeA))
            Assert.Equal("Nothing", FormatValue(Nothing, typeB))
            Assert.Equal("Nothing", FormatValue(Nothing, typeC))

            Assert.Equal("{A(Of Integer)}", FormatValue(typeA.Instantiate()))
            Assert.Equal("{B.ToString()}", FormatValue(typeB.Instantiate()))
            Assert.Equal("{B.ToString()}", FormatValue(typeC.Instantiate()))
        End Sub

        <Fact>
        Public Sub ValuesWithUnderlyingString()
            Assert.True(HasUnderlyingString("Test"))
            Assert.False(HasUnderlyingString(Nothing, GetType(String)))
            Assert.False(HasUnderlyingString(0))
            Assert.False(HasUnderlyingString(DkmEvaluationFlags.None)) ' Enum
            Assert.False(HasUnderlyingString("a"c))
            Assert.False(HasUnderlyingString({1, 2, 3}))
            Assert.False(HasUnderlyingString(New Object()))
            Assert.False(HasUnderlyingString(0, GetType(Integer).MakePointerType()))
        End Sub

        <Fact>
        Public Sub VisualizeString()
            Assert.Equal(vbCrLf, GetUnderlyingString(vbCrLf))
        End Sub

        <Fact>
        Public Sub VisualizeSqlString()
            Dim source = "
Namespace System.Data.SqlTypes
    Public Structure SqlString
        Private m_value As String

        Public Sub New(data As String)
            m_value = data
        End Sub
    End Structure
End Namespace
"
            Dim assembly = GetAssembly(source)
            Dim type = assembly.GetType("System.Data.SqlTypes.SqlString")

            Dim sqlString = type.Instantiate({"Test"})

            Assert.Equal("Test", GetUnderlyingString(sqlString))
        End Sub

        <Fact>
        Public Sub VisualizeXNode()
            Dim source = "
Namespace System.Xml.Linq
    Public Class XNode
        Public Overrides Function ToString() As String
            Return ""Test1""
        End Function
    End Class

    Public Class XContainer : Inherits XNode
    End Class

    Public Class XElement : Inherits XContainer
        Public Overrides Function ToString() As String
            Return ""Test2""
        End Function
    End Class
End Namespace
"
            Dim assembly = GetAssembly(source)
            Dim xnType = assembly.GetType("System.Xml.Linq.XNode")
            Dim xeType = assembly.GetType("System.Xml.Linq.XElement")

            Assert.Equal("Test1", GetUnderlyingString(xnType.Instantiate()))
            Assert.Equal("Test2", GetUnderlyingString(xeType.Instantiate()))
        End Sub

        <Fact>
        Public Sub Dates()
            Assert.Equal("#1/1/0001 12:00:00 AM#", FormatValue(New Date(0)))
            Assert.Equal("#1/1/1970 12:00:00 AM#", FormatValue(New Date(1970, 1, 1)))
            Assert.Equal("#1/1/0001 12:00:00 PM#", FormatValue(New Date(1, 1, 1, 12, 0, 0, 0)))
            Assert.Equal("#1/1/0001 12:00:00 PM#", FormatValue(New Date(1, 1, 1, 12, 0, 0, 0), useHexadecimal:=True)) ' Hexadecimal setting shouldn't change output
            ' DateTimeKind is stored in the top two bits of the ULong value that backs the DateTime instance.
            ' We need to make sure we don't throw an Exception when those bits are set to non-zero values.
            Assert.Equal("#1/1/1970 12:00:00 AM#", FormatValue(New Date(&H89F7FF5F7B58000, DateTimeKind.Local)))
            Assert.Equal("#1/1/1970 12:00:00 AM#", FormatValue(New Date(&H89F7FF5F7B58000, DateTimeKind.Utc)))
        End Sub

        <Fact>
        Public Sub HostValueNotFound_Integer()
            Dim clrValue = New DkmClrValue(value:=Nothing, hostObjectValue:=Nothing, New DkmClrType(CType(GetType(Integer), TypeImpl)),
                alias:=Nothing, evalFlags:=DkmEvaluationResultFlags.None, valueFlags:=DkmClrValueFlags.None)

            Assert.Equal(Resources.HostValueNotFound, FormatValue(clrValue))
        End Sub

        <Fact>
        Public Sub HostValueNotFound_char()
            Dim clrValue = New DkmClrValue(value:=Nothing, hostObjectValue:=Nothing, New DkmClrType(CType(GetType(Char), TypeImpl)),
                                           alias:=Nothing, evalFlags:=DkmEvaluationResultFlags.None, valueFlags:=DkmClrValueFlags.None)

            Assert.Equal(Resources.HostValueNotFound, FormatValue(clrValue))
        End Sub

        <Fact>
        Public Sub HostValueNotFound_IntPtr()
            Dim clrValue = New DkmClrValue(value:=Nothing, hostObjectValue:=Nothing, New DkmClrType(CType(GetType(IntPtr), TypeImpl)),
                                           alias:=Nothing, evalFlags:=DkmEvaluationResultFlags.None, valueFlags:=DkmClrValueFlags.None)

            Assert.Equal(Resources.HostValueNotFound, FormatValue(clrValue))
        End Sub

        <Fact>
        Public Sub HostValueNotFound_UIntPtr()
            Dim clrValue = New DkmClrValue(value:=Nothing, hostObjectValue:=Nothing, New DkmClrType(CType(GetType(UIntPtr), TypeImpl)),
                                           alias:=Nothing, evalFlags:=DkmEvaluationResultFlags.None, valueFlags:=DkmClrValueFlags.None)

            Assert.Equal(Resources.HostValueNotFound, FormatValue(clrValue))
        End Sub

        <Fact>
        Public Sub HostValueNotFound_Enum()
            Dim clrValue = New DkmClrValue(value:=Nothing, hostObjectValue:=Nothing, New DkmClrType(CType(GetType(TestEnum), TypeImpl)),
                                           alias:=Nothing, evalFlags:=DkmEvaluationResultFlags.None, valueFlags:=DkmClrValueFlags.None)

            Assert.Equal(Resources.HostValueNotFound, FormatValue(clrValue))
        End Sub

        ' DateTime is a primitive type in VB but not in C#.
        <Fact>
        Public Sub HostValueNotFound_DateTime()
            Dim clrValue = New DkmClrValue(value:=Nothing, hostObjectValue:=Nothing, New DkmClrType(CType(GetType(DateTime), TypeImpl)),
                                           alias:=Nothing, evalFlags:=DkmEvaluationResultFlags.None, valueFlags:=DkmClrValueFlags.None)

            Assert.Equal(Resources.HostValueNotFound, FormatValue(clrValue))
        End Sub

        Private Enum TestEnum
            One
        End Enum

    End Class

End Namespace
